package com.spider.lwlk.mysql.task

import com.spider.lwlk.mysql.config.DBConfig
import com.spider.lwlk.mongodb.task.taskstatus.TaskStatus
import groovyx.net.http.HTTPBuilder
import groovy.sql.Sql

import static groovyx.net.http.ContentType.TEXT
import static groovyx.net.http.Method.GET

class BaseTask {

    String path

    TaskStatus taskStatus = TaskStatus.Waiting

    final doGet() {

        def http = new HTTPBuilder()

        http.request(path, GET, TEXT, onRequest())

        this
    }

    final doUpdate() {

        try {

            Sql.withInstance(DBConfig.dbArgs, onFilter())

            Sql.withInstance(DBConfig.dbArgs, onUpdate())

            Sql.withInstance(DBConfig.dbArgs, onCompleted())
        }

        catch (Exception e) {

            taskStatus = TaskStatus.UpdateFailure

            doExceptionLog("$path\n${ e.getStackTrace() }")
        }
    }

    final doExceptionLog(String logContent) {

        Sql.withInstance(DBConfig.dbArgs, onException(logContent))
    }

    final isCompleted() { taskStatus == TaskStatus.Success }

    final onRequest() {

        {   req ->

            uri.path = path

            uri.query = [:]

            headers.'User-Agent' = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36"

            headers.Accept = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'

            response.success = onSuccess()

            response.failure = onFailure()
        }
    }

    def onSuccess() { { resp, reader -> taskStatus = TaskStatus.RequestSuccess } }

    def onFailure() {

        {   resp ->

            taskStatus = TaskStatus.RequestFailure

            doExceptionLog("$path\n${ resp.statusLine.statusCode }\n${ resp.statusLine.reasonPhrase }")
        }
    }

    def onFilter() { { Sql db -> } }

    def onUpdate() { { Sql db -> taskStatus = TaskStatus.UpdateSuccess } }

    def onCompleted() { { Sql db -> taskStatus = TaskStatus.Success } }

    def onException(String logContent) {

        { Sql db -> db.executeInsert("insert into log_table(log_content, log_time) values(?, now())",
                [logContent]) }
    }
}
